/*
 * Copyright (C) 2016 Jared Rummler
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zhuangfei.ohos_timetableview.spinner;

import com.zhuangfei.ohos_timetableview.ResourceTable;
import com.zhuangfei.timetable.utils.ScreenUtils;

import ohos.aafwk.ability.Ability;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.BaseDialog;
import ohos.agp.window.dialog.IDialog;
import ohos.agp.window.dialog.PopupDialog;
import ohos.app.AbilityContext;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.TouchEvent;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * A spinner that shows a {@link PopupDialog} under the view when clicked.
 *
 * @since 2021-03-29
 */
public class MaterialSpinner extends Text implements Component.TouchEventListener {
    /**
     * HiLogLabel
     */
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MaterialSpinner");

    private OnNothingSelectedListener onNothingSelectedListener;
    private OnItemSelectedListener onItemSelectedListener;
    private com.zhuangfei.ohos_timetableview.spinner.MaterialSpinnerBaseAdapter adapter;
    private PopupDialog popupWindow;
    private ListContainer listView;
    private PixelMapElement arrowDrawable;
    private boolean hideArrow;
    private boolean nothingSelected;
    private int spinnerWidth;
    private int popupWindowMaxHeight;
    private int popupWindowHeight;
    private int selectedIndex;
    private int backgroundColor;
    private Element backgroundSelector;
    private int arrowColor;
    private int arrowColorDisabled;
    private int textColor;
    private int textColorButton;
    private int textSize;
    private int hintColor;
    private int popupPaddingTop;
    private int popupPaddingLeft;
    private int popupPaddingBottom;
    private int popupPaddingRight;
    private String hintText;
    private com.zhuangfei.ohos_timetableview.spinner.MaterialSpinnerBaseAdapter mAdapter;

    /**
     * 构造方法
     *
     * @param context
     * @param attrs
     */
    public MaterialSpinner(Context context, AttrSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    /**
     * MaterialSpinner
     *
     * @param context
     * @param attrs
     * @param styleName
     */
    public MaterialSpinner(Context context, AttrSet attrs, String styleName) {
        super(context, attrs, styleName);
        init(context, attrs);
    }

    private boolean rtl;

    private void init(Context context, AttrSet attrs) {
        HiLog.info(LABEL, "init() ");
        Color defaultColor = getTextColor();
        rtl = com.zhuangfei.ohos_timetableview.spinner.Utils.isRtl(context);

        int paddingLeft = 0;
        int paddingTop = 0;
        int paddingRight = 0;
        int paddingBottom = 0;
        int defaultPaddingLeft;
        int defaultPaddingTop;
        int defaultPaddingRight;
        int defaultPaddingBottom;
        int defaultPopupPaddingLeft;
        int defaultPopupPaddingTop;
        int defaultPopupPaddingRight;
        int defaultPopupPaddingBottom;

        spinnerWidth = this.getWidth();

        ResourceManager resourceManager = getResourceManager();
        try {
            defaultPaddingLeft = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_top).getFloat();
            defaultPaddingRight = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_top).getFloat();
            defaultPaddingBottom = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_top).getFloat();
            defaultPaddingTop = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_top).getFloat();
            if (rtl) {
                defaultPaddingRight = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_left).getFloat();
            } else {
                defaultPaddingLeft = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_left).getFloat();
            }
            defaultPopupPaddingLeft = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_left).getFloat();
            defaultPopupPaddingRight = (int) resourceManager.getElement(
                    ResourceTable.Float_ms__padding_left).getFloat();

            defaultPopupPaddingTop = (int) resourceManager.getElement(ResourceTable.Float_ms__padding_top).getFloat();
            defaultPopupPaddingBottom = (int) resourceManager.getElement(
                    ResourceTable.Float_ms__padding_top).getFloat();

            backgroundColor = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getIntColor(attrs,
                    "ms_background_color", Color.WHITE.getValue());
            backgroundSelector = attrs.getAttr("ms_background_selector").get().getElement();
            HiLog.info(LABEL, "backgroundSelector = " + backgroundSelector);
            textColor = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getIntColor(attrs, "ms_text_color",
                    defaultColor.getValue());
            textColorButton = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getIntColor(attrs,
                    "ms_text_color_button", defaultColor.getValue());
            hintColor = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getIntColor(attrs,
                    "ms_hint_color", defaultColor.getValue());
            arrowColor = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getIntColor(attrs, "ms_arrow_tint", textColor);
            hideArrow = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getBoolean(attrs, "ms_hide_arrow", false);
            hintText = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getString(attrs, "ms_hint", "");

            popupWindowMaxHeight = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_dropdown_max_height", 1680);
            popupWindowHeight = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getLayoutDimension(attrs,
                    "ms_dropdown_height", ComponentContainer.LayoutConfig.MATCH_CONTENT);
            paddingTop = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_padding_top", defaultPaddingTop);
            paddingLeft = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_padding_left", defaultPaddingLeft);
            paddingBottom = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_padding_bottom", defaultPaddingBottom);
            paddingRight = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_padding_right", defaultPaddingRight);
            popupPaddingTop = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_popup_padding_top", defaultPopupPaddingTop);
            popupPaddingLeft = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_popup_padding_left", defaultPopupPaddingLeft);
            popupPaddingBottom = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_popup_padding_bottom", defaultPopupPaddingBottom);
            popupPaddingRight = com.zhuangfei.ohos_timetableview.spinner.TypedAttrUtils.getDimensionPixelSize(attrs,
                    "ms_popup_padding_right", defaultPopupPaddingRight);
            arrowColorDisabled = com.zhuangfei.ohos_timetableview.spinner.Utils.lighter(arrowColor, 0.8f);
            HiLog.info(LABEL, "arrowColorDisabled = " + arrowColorDisabled);

            HiLog.info(LABEL, "init textColor = " + textColor
                    + ", hideArrow = " + hideArrow
                    + ", hintText = " + hintText
                    + ", popupWindowMaxHeight = " + popupWindowMaxHeight
                    + ", paddingTop = " + paddingTop
                    + ", popupPaddingLeft = " + popupPaddingLeft
            );
        } catch (IOException e) {
            HiLog.info(LABEL, e.toString());
        } catch (NotExistException e) {
            HiLog.info(LABEL, e.toString());
        } catch (WrongTypeException e) {
            HiLog.info(LABEL, e.toString());
        }
        nothingSelected = true;

        setTextAlignment(TextAlignment.VERTICAL_CENTER | TextAlignment.START);
        setClickable(true);
        setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);

        if (rtl) {
            setLayoutDirection(LayoutDirection.RTL);
        }

        if (!hideArrow) {
            arrowDrawable = com.zhuangfei.ohos_timetableview.spinner.Utils.getPixelMapElement(context, ResourceTable.Media_ic_more);
            Element[] drawables = getAroundElements();
            if (rtl) {
                drawables[0] = arrowDrawable;
            } else {
                drawables[2] = arrowDrawable;
            }
            setAroundElements(drawables[0], drawables[1], drawables[2], drawables[3]);
        }
        if (textColor != defaultColor.getValue()) {
            setTextColor(new Color(textColor));
        }
        textSize = getTextSize();

        initPopupWindow(context);
        setTouchEventListener(this);
    }

    private void initPopupWindow(Context context) {
        ComponentContainer customToastLayout = (ComponentContainer)
                LayoutScatter.getInstance(context).parse(ResourceTable.Layout_list_spinner, null, false);
        listView = (ListContainer) customToastLayout.findComponentById(ResourceTable.Id_lv_spinner);
        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        listView.setLayoutConfig(layoutConfig);
        listView.setId(getId());
        listView.setLayoutManager(new DirectionalLayoutManager());
        listView.setScrollbarColor(Color.DKGRAY);
        listView.setScrollbarThickness(0);
        listView.setScrollbarFadingEnabled(true);
        listView.enableScrollBar(AXIS_Y, true);
        listView.setScrollbarRoundRect(true);
        listView.setScrollbarRadius(10);
        listView.setItemProvider(mAdapter);
        listView.setItemClickedListener(new ListContainer.ItemClickedListener() {

            @Override
            public void onItemClicked(ListContainer parent, Component view, int position, long id) {
                selectedIndex = position;
                nothingSelected = false;
                Object item = adapter.get(position);
                adapter.notifyItemSelected(position);
                setTextColor(new Color(MaterialSpinner.this.textColor));
                collapse();
                if (onItemSelectedListener != null) {
                    onItemSelectedListener.onItemSelected(MaterialSpinner.this, position, id, item);
                }
            }
        });

        popupWindow = new PopupDialog(context, null);
        popupWindow.setCustomComponent(customToastLayout);
        HiLog.info(LABEL, "backgroundColor = " + (backgroundColor != Color.WHITE.getValue()));
        if (backgroundColor != Color.WHITE.getValue()) { // default color is white
            ShapeElement element = new ShapeElement();
            element.setRgbColor(RgbColor.fromArgbInt(backgroundColor));
            setBackground(element);
        }
        popupWindow.setDialogListener(new BaseDialog.DialogListener() {
            @Override
            public boolean isTouchOutside() {
                HiLog.info(LABEL, "setDialogListener isTouchOutside "
                        + nothingSelected + ", " + onNothingSelectedListener);
                if (popupWindow != null) {
                    popupWindow.destroy();
                    popupWindow = null;
                }
                if (nothingSelected && onNothingSelectedListener != null) {
                    onNothingSelectedListener.onNothingSelected(MaterialSpinner.this);
                }
                if (!hideArrow) {
                    animateArrow(false);
                }
                return true;
            }
        });
        popupWindow.registerDisplayCallback(new PopupDialog.DisplayCallback() {
            @Override
            public void onDisplay(IDialog dialog) {
                HiLog.info(LABEL, "registerDisplayCallback iDialog " + dialog);
            }
        });
        popupWindow.registerRemoveCallback(new BaseDialog.RemoveCallback() {
            @Override
            public void onRemove(IDialog dialog) {
                HiLog.info(LABEL, "registerRemoveCallback iDialog " + dialog);
            }
        });
    }


    @Override
    public void setLayoutConfig(ComponentContainer.LayoutConfig config) {
        super.setLayoutConfig(config);
        HiLog.info(LABEL, "setLayoutConfig setLayoutConfig setLayoutConfig " + spinnerWidth);
    }

    /**
     * isShow
     */
    private boolean isShow = false;

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        HiLog.error(LABEL, "onTouchEvent = " + touchEvent.getAction());
        if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) {
            if (isEnabled() && isClickable()) {
                expand();
            }
        } else if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {
            return true;
        }
        return false;
    }

    /**
     * setShowFalse
     */
    public void setShowFalse() {
        isShow = false;
    }

    /**
     * setShowFalse
     *
     * @param isShows
     */
    public void setShowFalse(Boolean isShows) {
        isShow = isShows;
    }

    @Override
    public void setTextSize(int size) {
        HiLog.info(LABEL, "setTextSize adapter = " + adapter + ", textSize = " + textSize);
        if (adapter != null) {
            adapter.setTextSize(textSize);
            adapter.notifyDataChanged();
        }
        super.setTextSize(size);
    }

    @Override
    public void setTextColor(Color color) {
        HiLog.info(LABEL, "@Override setTextColor adapter = " + adapter);
        textColor = color.getValue();
        if (adapter != null) {
            adapter.setTextColor(textColor);
            adapter.notifyDataChanged();
        }
        super.setTextColor(new Color(textColorButton));
    }

    /**
     * setHintColor
     *
     * @param color
     */
    public void setHintColor(Color color) {
        hintColor = color.getValue();
        super.setTextColor(color);
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
    }

    /**
     * the selected item position
     *
     * @return selectedIndex
     */
    public int getSelectedIndex() {
        return selectedIndex;
    }

    /**
     * Register a callback to be invoked when an item in the dropdown is selected
     *
     * @param onItemSelectedListener The callback that will run
     */
    public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
        this.onItemSelectedListener = onItemSelectedListener;
    }

    /**
     * Register a callback to be invoked when the {@link PopupDialog} is shown but the user didn't select an item.
     *
     * @param onNothingSelectedListener the callback that will run
     */
    public void setOnNothingSelectedListener(OnNothingSelectedListener onNothingSelectedListener) {
        this.onNothingSelectedListener = onNothingSelectedListener;
    }

    /**
     * Set the dropdown items
     *
     * @param items A list of items
     * @param <T>   The item type
     */
    public <T> void setItems(T... items) {
        setItems(Arrays.asList(items));
    }

    /**
     * Set the dropdown items
     *
     * @param items A list of items
     * @param <T>   The item type
     */
    public <T> void setItems(List<T> items) {
        adapter = new com.zhuangfei.ohos_timetableview.spinner.MaterialSpinnerAdapter<>(getContext(), items)
                .setPopupPadding(popupPaddingLeft, popupPaddingTop, popupPaddingRight, popupPaddingBottom)
                .setTextSize(textSize)
                .setTextColor(textColor);
        setAdapterInternal(adapter);
    }

    /**
     * Set the custom adapter for the dropdown items
     *
     * @param adapter The adapter
     * @param <T>     The type
     */
    public <T> void setAdapter(com.zhuangfei.ohos_timetableview.spinner.MaterialSpinnerAdapter<T> adapter) {
        this.adapter = adapter;
        this.adapter.setTextColor(textColor);
        this.adapter.setPopupPadding(popupPaddingLeft, popupPaddingTop, popupPaddingRight, popupPaddingBottom);
        setAdapterInternal(adapter);
    }

    private void setAdapterInternal(com.zhuangfei.ohos_timetableview.spinner.MaterialSpinnerBaseAdapter adapterInternal) {
        this.mAdapter = adapterInternal;
        boolean shouldResetPopupHeight = listView.getItemProvider() != null;
        adapterInternal.setHintEnabled(!com.zhuangfei.ohos_timetableview.spinner.Utils.isEmpty(hintText));
        listView.setItemProvider(adapterInternal);
        HiLog.info(LABEL, "selectedIndex = " + selectedIndex + ", shouldResetPopupHeight = " + shouldResetPopupHeight);
        if (selectedIndex >= adapterInternal.getCount()) {
            selectedIndex = 0;
        }
        if (adapterInternal.getItems().size() > 0) {
            if (nothingSelected && !com.zhuangfei.ohos_timetableview.spinner.Utils.isEmpty(hintText)) {
                setText(hintText);
                setHintColor(new Color(hintColor));
            } else {
                setTextColor(new Color(textColor));
            }
        } else {
            setText("");
        }
        if (shouldResetPopupHeight) {
            popupWindow.setSize(getWidth(), adapterInternal.getCount() * ScreenUtils.pxToFp(mContext, 36) + 10);
            listView.setComponentSize(getWidth(), adapterInternal.getCount() * ScreenUtils.pxToFp(mContext, 36) + 10);
        }
    }

    /**
     * 有更改 : 调整弹窗显示位置
     * Show the dropdown menu
     */
    public void expand() {
        HiLog.error(LABEL, "expand = " + isShow + hideArrow);
        if (!isShow) {
            if (!hideArrow) {
                animateArrow(true);
            }
            nothingSelected = true;
            initPopupWindow(mContext);

            popupWindow.setSize(ScreenUtils.getDisplayWidth(mContext) / 5 * 2,
                    adapter.getCount() * ScreenUtils.pxToFp(mContext, 36) + 10);
            listView.setComponentSize(ScreenUtils.getDisplayWidth(mContext) / 5 * 2,
                    adapter.getCount() * ScreenUtils.pxToFp(mContext, 36) + 10);
            int[] locationOnScreen = this.getLocationOnScreen();
            HiLog.info(LABEL, "locationOnScreen[1] = " + locationOnScreen[1] + ", "
                    + spinnerWidth + ",locationOnScreen[1]" + locationOnScreen[1]);
            popupWindow.showOnCertainPosition(LayoutAlignment.LEFT | LayoutAlignment.TOP,
                    locationOnScreen[0] + 60, locationOnScreen[1] + this.getComponentSize().getSizeYToInt() + 10);
            isShow = true;
        }
    }

    /**
     * Closes the dropdown menu
     */
    public void collapse() {
        ComponentParent componentParent = listView.getComponentParent();
        if (componentParent != null) {
            componentParent.removeComponent(listView);
        }
        listView = null;
        popupWindow.destroy();
        popupWindow = null;
    }

    /**
     * Set the tint color for the dropdown arrow
     *
     * @param color
     */
    public void setArrowColor(int color) {
        arrowColor = color;
        arrowColorDisabled = com.zhuangfei.ohos_timetableview.spinner.Utils.lighter(arrowColor, 0.8f);
    }

    private boolean canShowPopup() {
        Ability activity = getActivity();
        HiLog.info(LABEL, "activity = " + activity);
        if (activity == null || activity.isTerminating()) {
            return false;
        }
        boolean isLaidOut;
        isLaidOut = getWidth() > 0 && getHeight() > 0;
        return isLaidOut;
    }

    private Ability getActivity() {
        Context context = getContext();
        while (context instanceof AbilityContext) {
            if (context instanceof Ability) {
                return (Ability) context;
            }
            context = ((AbilityContext) context).getContext();
        }
        return null;
    }

    private void animateArrow(boolean shouldRotateUp) {
        int start = shouldRotateUp ? 0 : 10000;
        int end = shouldRotateUp ? 10000 : 0;
        if (rtl) {
            setLayoutDirection(LayoutDirection.RTL);
        }
        arrowDrawable = com.zhuangfei.ohos_timetableview.spinner.Utils.getPixelMapElement(mContext, ResourceTable.Media_ic_more);
        /**
         * 旋转图片 动作
         */
        Matrix matrix = new Matrix();
        /**
         * 旋转角度
         */
        matrix.setRotate(45);
        Element[] drawables = getAroundElements();
        if (rtl) {
            drawables[0] = arrowDrawable;
        } else {
            drawables[2] = arrowDrawable;
        }
        setAroundElements(drawables[0], drawables[1], drawables[2], drawables[3]);
    }

    /**
     * Set the maximum height of the dropdown menu.
     *
     * @param height the height in pixels
     */
    public void setDropdownMaxHeight(int height) {
        popupWindowMaxHeight = height;
    }

    /**
     * Set the height of the dropdown menu
     *
     * @param height the height in pixels
     */
    public void setDropdownHeight(int height) {
        popupWindowHeight = height;
    }

    private int calculatePopupWindowHeight() {
        HiLog.info(LABEL, "calculatePopupWindowHeight adapter = " + adapter);
        if (adapter == null) {
            return ComponentContainer.LayoutConfig.MATCH_CONTENT;
        }
        float itemHeight = 0;
        try {
            itemHeight = this.getResourceManager().getElement(ResourceTable.Float_ms__item_height).getFloat();
        } catch (IOException e) {
            HiLog.info(LABEL, e.toString());
        } catch (NotExistException e) {
            HiLog.info(LABEL, e.toString());
        } catch (WrongTypeException e) {
            HiLog.info(LABEL, e.toString());
        }
        float listViewHeight = adapter.getCount() * itemHeight;
        HiLog.info(LABEL, "itemHeight = " + itemHeight + ", listViewHeight = "
                + listViewHeight + ", popupWindowMaxHeight = " + popupWindowMaxHeight
                + ", popupWindowHeight = " + popupWindowHeight);
        if (popupWindowMaxHeight > 0 && listViewHeight > popupWindowMaxHeight) {
            HiLog.info(LABEL, "if = ");
            return popupWindowMaxHeight;
        } else if (popupWindowHeight != ComponentContainer.LayoutConfig.MATCH_PARENT
                && popupWindowHeight != ComponentContainer.LayoutConfig.MATCH_CONTENT
                && popupWindowHeight <= listViewHeight) {
            HiLog.info(LABEL, "else if = ");
            return popupWindowHeight;
        } else if (listViewHeight == 0 && adapter.getItems().size() == 1) {
            HiLog.info(LABEL, "size() == 1 ");
            return (int) itemHeight;
        } else if (popupWindowHeight == ComponentContainer.LayoutConfig.MATCH_CONTENT) {
            HiLog.info(LABEL, "else MATCH_CONTENT = ");
            if (popupWindowHeight != 0) {
                return popupWindowHeight;
            } else {
                return popupWindowMaxHeight;
            }
        } else if (popupWindowHeight == ComponentContainer.LayoutConfig.MATCH_PARENT) {
            HiLog.info(LABEL, "else MATCH_PARENT = ");
            if (popupWindowHeight > 0) {
                return popupWindowHeight;
            } else {
                return popupWindowMaxHeight;
            }
        }
        return ComponentContainer.LayoutConfig.MATCH_CONTENT;
    }

    /**
     * Get the {@link PopupDialog}.
     *
     * @return The {@link PopupDialog} that is displayed when the view has been clicked.
     */
    public PopupDialog getPopupWindow() {
        return popupWindow;
    }

    /**
     * Get the {@link ListContainer} that is used in the dropdown menu
     *
     * @return the ListView shown in the PopupDialog.
     */
    public ListContainer getListView() {
        return listView;
    }

    /**
     * Interface definition for a callback to be invoked when an item in this view has been selected.
     * <p>
     * OnItemSelectedListener
     *
     * @param <T> OnItemSelectedListener
     * @since 2021-03-29
     */
    public interface OnItemSelectedListener<T> {

        /**
         * <p>Callback method to be invoked when an item in this view has been selected.
         * This callback is invoked only when
         * the newly selected position is different from the previously selected position or if there was no selected
         * item.</p>
         *
         * @param view     The {@link MaterialSpinner} view
         * @param position The position of the view in the adapter
         * @param id       The row id of the item that is selected
         * @param item     The selected item
         */
        void onItemSelected(MaterialSpinner view, int position, long id, T item);
    }

    /**
     * OnNothingSelectedListener
     * <p>
     * Interface definition for a callback to be invoked when the dropdown is dismissed and no item was selected.
     *
     * @since 2021-03-29
     */
    public interface OnNothingSelectedListener {

        /**
         * Callback method to be invoked when the {@link PopupDialog} is dismissed and no item was selected.
         *
         * @param spinner the {@link MaterialSpinner}
         */
        void onNothingSelected(MaterialSpinner spinner);
    }
}